import type { FormLabelProps } from '@invoke-ai/ui-library';
import { Expander, Flex, FormControlGroup, StandaloneAccordion } from '@invoke-ai/ui-library';
import { EMPTY_ARRAY } from 'app/store/constants';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppSelector } from 'app/store/storeHooks';
import {
  selectModelSupportsOptimizedDenoising,
  selectShouldRandomizeSeed,
} from 'features/controlLayers/store/paramsSlice';
import { selectBbox, selectScaleMethod } from 'features/controlLayers/store/selectors';
import { ParamOptimizedDenoisingToggle } from 'features/parameters/components/Advanced/ParamOptimizedDenoisingToggle';
import BboxScaledHeight from 'features/parameters/components/Bbox/BboxScaledHeight';
import BboxScaledWidth from 'features/parameters/components/Bbox/BboxScaledWidth';
import BboxScaleMethod from 'features/parameters/components/Bbox/BboxScaleMethod';
import { BboxSettings } from 'features/parameters/components/Bbox/BboxSettings';
import { ParamSeed } from 'features/parameters/components/Seed/ParamSeed';
import { useExpanderToggle } from 'features/settingsAccordions/hooks/useExpanderToggle';
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';

const selectBadges = createMemoizedSelector([selectBbox, selectShouldRandomizeSeed], (bbox, shouldRandomizeSeed) => {
  const badges: string[] = [];

  const { aspectRatio, rect } = bbox;
  const { width, height } = rect;

  badges.push(`${width}×${height}`);

  badges.push(aspectRatio.id);

  if (aspectRatio.isLocked) {
    badges.push('locked');
  }

  if (!shouldRandomizeSeed) {
    badges.push('Manual Seed');
  }

  if (badges.length === 0) {
    return EMPTY_ARRAY;
  }

  return badges;
});

const scalingLabelProps: FormLabelProps = {
  minW: '4.5rem',
};

export const CanvasTabImageSettingsAccordion = memo(() => {
  const { t } = useTranslation();
  const badges = useAppSelector(selectBadges);
  const scaleMethod = useAppSelector(selectScaleMethod);
  const { isOpen: isOpenAccordion, onToggle: onToggleAccordion } = useStandaloneAccordionToggle({
    id: 'image-settings',
    defaultIsOpen: true,
  });
  const { isOpen: isOpenExpander, onToggle: onToggleExpander } = useExpanderToggle({
    id: 'image-settings-advanced',
    defaultIsOpen: false,
  });
  const modelSupportsOptimizedDenoising = useAppSelector(selectModelSupportsOptimizedDenoising);

  return (
    <StandaloneAccordion
      label={t('accordions.image.title')}
      badges={badges}
      isOpen={isOpenAccordion}
      onToggle={onToggleAccordion}
    >
      <Flex px={4} pt={4} pb={0} w="full" h="full" flexDir="column" data-testid="image-settings-accordion">
        <BboxSettings />
        <ParamSeed pt={3} pb={0} />
        <Expander label={t('accordions.advanced.options')} isOpen={isOpenExpander} onToggle={onToggleExpander}>
          <Flex gap={4} pb={4} flexDir="column">
            {modelSupportsOptimizedDenoising && <ParamOptimizedDenoisingToggle />}
            <BboxScaleMethod />
            {scaleMethod !== 'none' && (
              <FormControlGroup formLabelProps={scalingLabelProps}>
                <BboxScaledWidth />
                <BboxScaledHeight />
              </FormControlGroup>
            )}
          </Flex>
        </Expander>
      </Flex>
    </StandaloneAccordion>
  );
});

CanvasTabImageSettingsAccordion.displayName = 'CanvasTabImageSettingsAccordion';
